/*
    * Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd.
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
 */

#include <cstdlib>
#include <limits.h>
#include <sys/stat.h>
#include <unistd.h>
#include <iostream>  
#include <fstream>  
#include <cstring>

#include "system_ability.h"
#include "iremote_object.h"
#include "system_ability_definition.h"

#include "file_share_service.h"
#include "accesstoken_kit.h"
#include "ipc_skeleton.h"
#include "sandbox_helper.h"
#include "file_share_config.h"

namespace OHOS {
namespace FileShare {

REGISTER_SYSTEM_ABILITY_BY_ID(FileShareService, FILE_SHARE_SERVICE_ID, true);
FileShareService::FileShareService(int32_t systemAbilityId, bool runOnCreate)
    : SystemAbility(systemAbilityId, runOnCreate)
{

}

void FileShareService::OnStart()
{
   LOGD("OnStart start.");

    if (!SystemAbility::Publish(this))
    {
       LOGE("publish sa failed code:%{public}d , %{public}s", errno, strerror(errno));
        return;
    }
    AddSystemAbilityListener(SOFTBUS_SERVER_SA_ID);

    LOGD("OnStart success");
}

void FileShareService::OnStop()
{
    LOGD("OnStop start.");
    SendManager::GetInstance().DeInit();
}

void FileShareService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& networkID)
{
    LOGI("systemAbilityId: %{public}d added!", systemAbilityId);
    SendManager::GetInstance().Init();
}

void FileShareService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& networkID)
{
    LOGI("systemAbilityId: %{public}d removed!", systemAbilityId);
}

int32_t FileShareService::SendFile(SendTask &task)
{
    Security::AccessToken::HapTokenInfo hapTokenInfo;
    int ret = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(IPCSkeleton::GetCallingTokenID(), hapTokenInfo);
    if (ret != ERR_OK) {
        LOGE("GetHapTokenInfo error code: %{public}d", ret);
        return FS_GET_USER_ID_FAILED;
    }
    for (auto&& file : task.files) {
        ret = AppFileService::SandboxHelper::GetPhysicalPath(file.uri, std::to_string(hapTokenInfo.userID), file.path);
        if (ret != ERR_OK) {
            LOGE("GetPhysicalPath error code: %{public}d", ret);
            return FS_URI_TO_PATH_FAILED;
        }
    }
    return SendManager::GetInstance().SendFile(task);
}

int32_t FileShareService::RegisterFileShareCallback(const sptr<IFileShareCallback> &callback)
{
    return SendManager::GetInstance().RegisterFileShareCallback(callback);
}

int32_t FileShareService::UnRegisterFileShareCallback()
{
    return SendManager::GetInstance().UnRegisterFileShareCallback();
}

int32_t FileShareService::CancelSendFile(const std::string &deviceId, SendType type)
{
    switch (type) {
        case SendType::SRC:
            return SendManager::GetInstance().CancelSendFile(deviceId);
        case SendType::SINK:
            return SendManager::GetInstance().AbortReceiveFile(deviceId);
    }
    
}

int32_t FileShareService::SetShareStatus(const bool status)
{
    return SendManager::GetInstance().SetShareStatus(status);
}

int32_t FileShareService::GetShareStatus(bool &status)
{
    return SendManager::GetInstance().GetShareStatus(status);
}

std::string FileShareService::GetStoragePath()
{
    return  FileShareConfig::GetInstance().GetStoragePath();
}

int32_t FileShareService::SetStoragePath(std::string &path)
{
    return  FileShareConfig::GetInstance().SetStoragePath(path);
}

int32_t FileShareService::GetWorkDuration()
{
    return  FileShareConfig::GetInstance().GetWorkDuration();
}

int32_t FileShareService::SetWorkDuration(int32_t &time)
{
    return  FileShareConfig::GetInstance().SetWorkDuration(time);
}

int32_t FileShareService::RegisterShareStatusCallback(const std::string &bundleName, const sptr<IFileShareCallback> &callback)
{
    return SendManager::GetInstance().RegisterShareStatusCallback(bundleName, callback);
}

int32_t FileShareService::UnRegisterShareStatusCallback(const std::string &bundleName)
{
    return SendManager::GetInstance().UnRegisterShareStatusCallback(bundleName);
}

int32_t FileShareService::ChangeUuid(const uint16_t uuid)
{
    return SendManager::GetInstance().ChangeUuid(uuid);
}
} // namespace FileShare
} // namespace OHOS